<?php

namespace App\Services\RabbitMQ;

use App\Services\BaseServices;
use Illuminate\Support\Facades\Log;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Exception\AMQPHeartbeatMissedException;
use PhpAmqpLib\Message\AMQPMessage;
use phpDocumentor\Reflection\Types\Boolean;

class RabbitMQServices extends BaseServices
{
    /**
     * @var object $connection 队列连接对象
     */
    private $connection = null;

    /**
     * @var object $channel 队列通道对象
     */
    private $channel = null;

    /**
     * @var object $message 队列消息对象
     */
    private $message = null;

    public function __construct()
    {
        $this->connection = new AMQPStreamConnection(
            config('queue.connections.rabbitmq.host'),
            config('queue.connections.rabbitmq.port'),
            config('queue.connections.rabbitmq.login'),
            config('queue.connections.rabbitmq.password'),
            config('queue.connections.rabbitmq.vhost')
        );
        $this->channel = $this->connection->channel();
        $this->message = new AMQPMessage('',
            ['content_type' => 'json', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);
    }

    public function __destruct()
    {
        $this->channel->close();
        $this->connection->close();
        self::$instance = null;
    }

    /**
     * FunctionName：consumer
     * Description：消费队列
     * Author：lwl
     * @param string $queue 队列名称
     * @param boolean $bForceDelete 是否取后即删
     * @return AMQPMessage|null
     */
    public function consumer(string $queue,bool $bForceDelete = false)
    {
        try{
            // 取数据
            // 声明队列
            // 不检测同名队列，持久化，不允许其他队列访问，不自动删除队列
            $this->channel->queue_declare($queue,false,true,false,false);
            $message = $this->channel->basic_get($queue);
            if ($message && $bForceDelete){
                // 回复确认信息
                $this->channel->basic_ack($message->delivery_info["delivery_tag"]);
            }
        }catch (\Exception $exception){
            Log::info($exception->getMessage());
        }
        return $message;
    }

    /**
     * FunctionName：ack
     * Description：
     * Author：lwl
     * @param $nTag 消息传递标签
     * @return mixed
     */
    public function ack($nTag){
        try{
            $this->channel->basic_ack($nTag);
        }catch (\Exception $exception){
            dd($exception->getMessage());
        }
        return null;
    }
}
